package com.yvon.service.demo.jdk.juc;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : Yvon
 * @since : 2022-05-17
 */
public class MyBlockingQueueForCondition {

    /**
     * 定义一个队列
     */
    private Queue queue;

    /**
     * 队列最大容量为16
     */
    private int max = 16;

    /**
     * 锁
     */
    private ReentrantLock lock = new ReentrantLock();

    /**
     * 队列没有空的条件
     */
    private Condition notEmpty = lock.newCondition();

    /**
     * 队列没有满的条件
     */
    private Condition notFull = lock.newCondition();

    public MyBlockingQueueForCondition(int size) {
        this.max = size;
        this.queue = new LinkedList();
    }

    public void put(Object o) throws InterruptedException {
        lock.lock();
        try {
            // 判断队列是否已满
            while (queue.size() == max) {
                // 如果队列满了，阻塞生产者线程并释放Lock
                notFull.await();
            }
            // 如果没有满，放入数据，并唤醒等待的消费者线程
            queue.add(o);
            notEmpty.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public Object take() throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() == 0) {
                notEmpty.await();
            }
            Object item = queue.remove();
            notEmpty.signalAll();
            return item;
        } finally {
            lock.unlock();
        }
    }

    public int size() {
       return this.queue.size();
    }


}
